'use strict';
(function($) {
var woosb_timeout = null;
$(function() {
if ($('.woosb-wrap').length) {
$('.woosb-wrap').each(function() {
woosb_init($(this), 'ready');
});
}
});
$(document).on('woosq_loaded', function() {
// product bundles in quick view popup
woosb_init($('#woosq-popup .woosb-wrap'), 'woosq');
});
$(document).on('woovr_selected', function(e, selected, variations) {
var $wrap = variations.closest('.woosb-wrap');
var $product = variations.closest('.woosb-product');
if ($product.length) {
var _id = selected.attr('data-id');
var _price = selected.attr('data-price');
var _regular_price = selected.attr('data-regular-price');
var _price_html = selected.attr('data-pricehtml');
var _image_src = selected.attr('data-imagesrc');
var _purchasable = selected.attr('data-purchasable');
var _attrs = selected.attr('data-attrs');
var _availability = selected.attr('data-availability');
if (_purchasable === 'yes' && _id >= 0) {
// change data
$product.attr('data-id', _id);
$product.attr('data-price', _price);
// change price
woosb_change_price($product, _price, _regular_price, _price_html);
// change attributes
$product.attr('data-attrs', _attrs.replace(/\/$/, ''));
} else {
// reset data
$product.attr('data-id', 0);
$product.attr('data-price', $product.data('o_price'));
$product.attr('data-attrs', '');
// reset price
$product.find('.woosb-price-ori').show();
$product.find('.woosb-price-new').html('').hide();
}
// change image
if (_image_src && _image_src !== '') {
$product.find('.woosb-thumb-ori').hide();
$product.find('.woosb-thumb-new').
html('
').
show();
} else {
$product.find('.woosb-thumb-ori').show();
$product.find('.woosb-thumb-new').html('').hide();
}
// change availability
if (_availability && _availability !== '') {
$product.find('.woosb-availability').html(_availability).show();
} else {
$product.find('.woosb-availability').html('').hide();
}
// reset sku, weight & dimensions
if (typeof wc_reset_content === 'function') {
$('.product_meta .sku').wc_reset_content();
$('.product_weight, .woocommerce-product-attributes-item--weight .woocommerce-product-attributes-item__value').
wc_reset_content();
$('.product_dimensions, .woocommerce-product-attributes-item--dimensions .woocommerce-product-attributes-item__value').
wc_reset_content();
}
}
woosb_init($wrap, 'woovr_selected');
});
$(document).on('found_variation', function(e, t) {
var $wrap = $(e['target']).closest('.woosb-wrap');
var $product = $(e['target']).closest('.woosb-product');
if ($product.length) {
if (t['woosb_image'] !== undefined && t['woosb_image'] !== '') {
// change image
$product.find('.woosb-thumb-ori').hide();
$product.find('.woosb-thumb-new').html(t['woosb_image']).show();
} else {
$product.find('.woosb-thumb-ori').show();
$product.find('.woosb-thumb-new').html('').hide();
}
if (t['price_html'] !== undefined && t['price_html'] !== '' &&
t['display_price'] !== undefined && t['display_price'] !== '') {
woosb_change_price($product, t['display_price'],
t['display_regular_price'], t['price_html']);
}
if (t['variation_description'] !== undefined) {
$product.find('.woosb-variation-description').
html(t['variation_description']).
show();
} else {
$product.find('.woosb-variation-description').html('').hide();
}
if (t['is_purchasable']) {
// change the price
if (woosb_vars.bundled_price_from === 'regular_price' &&
t['display_regular_price'] !== undefined) {
$product.attr('data-price', t['display_regular_price']);
} else {
$product.attr('data-price', t['display_price']);
}
// change stock notice
if (t['is_in_stock']) {
$wrap.next('p.stock').show();
$product.attr('data-id', t['variation_id']);
} else {
$wrap.next('p.stock').hide();
$product.attr('data-id', 0);
}
// change availability
if (t['availability_html'] && t['availability_html'] !== '') {
$product.find('.woosb-availability').
html(t['availability_html']).
show();
} else {
$product.find('.woosb-availability').html('').hide();
}
// change attributes
var attrs = {};
$product.find('select[name^="attribute_"]').each(function() {
var attr_name = $(this).attr('name');
attrs[attr_name] = $(this).val();
});
$product.attr('data-attrs', JSON.stringify(attrs));
}
if (woosb_vars.change_image === 'no') {
// prevent changing the main image
$(e['target']).closest('.variations_form').trigger('reset_image');
}
// reset sku, weight & dimensions
if (typeof wc_reset_content === 'function') {
$('.product_meta .sku').wc_reset_content();
$('.product_weight, .woocommerce-product-attributes-item--weight .woocommerce-product-attributes-item__value').
wc_reset_content();
$('.product_dimensions, .woocommerce-product-attributes-item--dimensions .woocommerce-product-attributes-item__value').
wc_reset_content();
}
$(document).trigger('woosb_found_variation', [$product, t]);
woosb_init($wrap, 'found_variation');
}
});
$(document).on('reset_data', function(e) {
var $wrap = $(e['target']).closest('.woosb-wrap');
var $product = $(e['target']).closest('.woosb-product');
if ($product.length) {
// reset thumb
$product.find('.woosb-thumb-new').hide();
$product.find('.woosb-thumb-ori').show();
// reset price
$product.find('.woosb-price-new').hide();
$product.find('.woosb-price-ori').show();
// reset availability
$product.find('.woosb-availability').html('').hide();
// reset desc
$product.find('.woosb-variation-description').html('').hide();
// reset data
$product.attr('data-id', 0);
$product.attr('data-price', $product.data('o_price'));
$product.attr('data-attrs', '');
$(document).trigger('woosb_reset_data', [$product]);
woosb_init($wrap, 'reset_data');
}
});
$(document).
on('click touch',
'.woosb-quantity-input-plus, .woosb-quantity-input-minus',
function() {
// get values
var $qty = $(this).closest('.woosb-quantity').find('.woosb-qty');
if (!$qty.length) {
$qty = $(this).closest('.woosb-quantity').find('.qty');
}
var val = parseFloat($qty.val()),
max = parseFloat($qty.attr('max')),
min = parseFloat($qty.attr('min')), step = $qty.attr('step');
// format values
if (!val || val === '' || val === 'NaN') {
val = 0;
}
if (max === '' || max === 'NaN') {
max = '';
}
if (min === '' || min === 'NaN') {
min = 0;
}
if (step === 'any' || step === '' || step === undefined ||
parseFloat(step) === 'NaN') {
step = 1;
} else {
step = parseFloat(step);
}
// change the value
if ($(this).is('.woosb-quantity-input-plus')) {
if (max && (max == val || val > max)) {
$qty.val(max);
} else {
$qty.val((val + step).toFixed(woosb_decimal_places(step)));
}
} else {
if (min && (min == val || val < min)) {
$qty.val(min);
} else if (val > 0) {
$qty.val((val - step).toFixed(woosb_decimal_places(step)));
}
}
// trigger change event
$qty.trigger('change');
});
$(document).on('click touch', '.single_add_to_cart_button', function(e) {
var $this = $(this);
if ($this.hasClass('woosb-disabled')) {
e.preventDefault();
}
});
if ($('.woosb-qty').length) {
$(document).on('change', '.woosb-qty', function() {
var $this = $(this);
woosb_check_qty($this);
});
$(document).on('keyup', '.woosb-qty', function() {
var $this = $(this);
if (woosb_timeout != null) clearTimeout(woosb_timeout);
woosb_timeout = setTimeout(woosb_check_qty, 1000, $this);
});
} else {
$(document).on('change', '.woosb-quantity .qty', function() {
var $this = $(this);
woosb_check_qty($this);
});
$(document).on('keyup', '.woosb-quantity .qty', function() {
var $this = $(this);
if (woosb_timeout != null) clearTimeout(woosb_timeout);
woosb_timeout = setTimeout(woosb_check_qty, 1000, $this);
});
}
})(jQuery);
function woosb_init($wrap, context = null) {
woosb_check_ready($wrap, context);
woosb_save_ids($wrap, context);
jQuery(document).trigger('woosb_init', [$wrap, context]);
}
function woosb_check_ready($wrap) {
var qty = 0;
var total = 0;
var total_sale = 0;
var is_selection = false;
var selection_name = '';
var is_unpurchasable = false;
var unpurchasable_name = '';
var is_empty = true;
var is_min = false;
var is_max = false;
var is_total_min = false;
var is_total_max = false;
var wid = $wrap.attr('data-id');
var $products = $wrap.find('.woosb-products');
var $alert = $wrap.find('.woosb-alert');
var $ids = jQuery('.woosb-ids-' + wid);
var $btn = $ids.closest('form.cart').find('.single_add_to_cart_button');
var price_suffix = $products.attr('data-price-suffix');
var $total = $wrap.find('.woosb-total');
var $count = $wrap.find('.woosb-count');
var $price = jQuery('.woosb-price-' + wid);
var $woobt = jQuery('.woobt-wrap-' + wid);
var total_woobt = parseFloat($woobt.length ? $woobt.attr('data-total') : 0);
var discount = parseFloat($products.attr('data-discount'));
var discount_amount = parseFloat($products.attr('data-discount-amount'));
var fixed_price = $products.attr('data-fixed-price') === 'yes';
var has_optional = $products.attr('data-optional') === 'yes';
var has_variables = $products.attr('data-variables') === 'yes';
var exclude_unpurchasable = $products.attr('data-exclude-unpurchasable') ===
'yes';
var saved = '';
var is_discount = discount > 0 && discount < 100;
var is_discount_amount = discount_amount > 0;
var qty_min = parseFloat($products.attr('data-min'));
var qty_max = parseFloat($products.attr('data-max'));
var total_min = parseFloat($products.attr('data-total-min'));
var total_max = parseFloat($products.attr('data-total-max'));
var fix = Math.pow(10, Number(woosb_vars.price_decimals) + 1);
if (!$products.length || (!has_variables && !has_optional)) {
// don't need to do anything - already calculated in PHP
return;
}
// calculate price
if (!fixed_price) {
$products.find('.woosb-product').each(function() {
var $this = jQuery(this);
if ($this.hasClass('woosb-product-unpurchasable') &&
exclude_unpurchasable) {
// don't count this product
return;
}
if (parseFloat($this.attr('data-price')) > 0) {
var _qty = parseFloat($this.attr('data-qty'));
var _price = parseFloat($this.attr('data-price'));
total += woosb_round(_price, woosb_vars.price_decimals) * _qty;
if (!is_discount_amount && is_discount) {
_price *= (100 - discount) / 100;
}
_price = Math.round(_price * fix) / fix;
total_sale += woosb_round(_price, woosb_vars.price_decimals) * _qty;
}
});
if (is_discount_amount && discount_amount < total) {
total_sale = total - discount_amount;
saved = woosb_format_price(discount_amount);
} else if (is_discount) {
saved = woosb_round(discount, 2) + '%';
} else {
total_sale = total;
}
var total_html = woosb_price_html(total, total_sale);
var total_all_html = woosb_price_html(total + total_woobt,
total_sale + total_woobt);
if (saved !== '') {
total_html += ' ' +
woosb_vars.saved_text.replace('[d]', saved) + '';
}
// change the bundle total
$total.html('' + woosb_vars.price_text +
' ' + total_html + price_suffix +
'').
slideDown();
jQuery(document).
trigger('woosb_change_total', [$total, total_html, price_suffix]);
if (woosb_vars.change_price !== 'no') {
// change the main price
if (woosb_vars.change_price === 'yes_custom' &&
woosb_vars.price_selector != null && woosb_vars.price_selector !==
'') {
$price = jQuery(woosb_vars.price_selector);
}
if ($woobt.length) {
// woobt
$price.html(total_all_html + price_suffix);
} else {
if (typeof $price.attr('data-o_price') === 'undefined') {
$price.attr('data-o_price', woosb_encode_entities($price.html()));
}
$price.html(total_html + price_suffix);
}
}
if ($woobt.length) {
// woobt
$woobt.find('.woobt-products').
attr('data-product-price-html', total_html);
$woobt.find('.woobt-product-this').
attr('data-price', total_sale).
attr('data-regular-price', total);
woobt_init($woobt);
}
jQuery(document).
trigger('woosb_calc_price',
[total_sale, total, total_html, price_suffix, $wrap]);
}
// check ready
$products.find('.woosb-product').each(function() {
var $this = jQuery(this);
if (parseFloat($this.attr('data-qty')) > 0) {
is_empty = false;
qty += parseFloat($this.attr('data-qty'));
if (parseInt($this.attr('data-id')) === 0) {
is_selection = true;
if (selection_name === '') {
selection_name = $this.attr('data-name');
}
}
if ($this.hasClass('woosb-product-optional') &&
$this.hasClass('woosb-product-unpurchasable')) {
is_unpurchasable = true;
if (unpurchasable_name === '') {
unpurchasable_name = $this.attr('data-name');
}
}
}
});
if (has_optional) {
// check min
if (qty_min > 0 && qty < qty_min) {
is_min = true;
}
// check max
if (qty_max > 0 && qty > qty_max) {
is_max = true;
}
$count.html('' + woosb_vars.selected_text +
' ' + qty + '').
slideDown();
jQuery(document).
trigger('woosb_change_count', [$count, qty, qty_min, qty_max]);
}
if (!fixed_price) {
// check total min
if (total_min > 0 && total_sale < total_min) {
is_total_min = true;
}
// check total max
if (total_max > 0 && total_sale > total_max) {
is_total_max = true;
}
}
if (is_selection || is_unpurchasable || is_empty || is_min || is_max ||
is_total_min || is_total_max) {
$btn.addClass('woosb-disabled');
if (is_selection) {
$alert.html(woosb_vars.alert_selection.replace('[name]',
'' + selection_name + '')).slideDown();
} else if (is_unpurchasable) {
$alert.html(woosb_vars.alert_unpurchasable.replace('[name]',
'' + unpurchasable_name + '')).slideDown();
} else if (is_empty) {
$alert.html(woosb_vars.alert_empty).slideDown();
} else if (is_min) {
$alert.html(woosb_vars.alert_min.replace('[min]', qty_min).
replace('[selected]', qty)).slideDown();
} else if (is_max) {
$alert.html(woosb_vars.alert_max.replace('[max]', qty_max).
replace('[selected]', qty)).slideDown();
} else if (is_total_min) {
$alert.html(woosb_vars.alert_total_min.replace('[min]',
woosb_format_price(total_min)).
replace('[total]', woosb_format_price(total_sale))).slideDown();
} else if (is_total_max) {
$alert.html(woosb_vars.alert_total_max.replace('[max]',
woosb_format_price(total_max)).
replace('[total]', woosb_format_price(total_sale))).slideDown();
}
jQuery(document).trigger('woosb_check_ready', [
false,
is_selection,
is_unpurchasable,
is_empty,
is_min,
is_max,
is_total_min,
is_total_max,
$wrap]);
} else {
$alert.html('').slideUp();
$btn.removeClass('woosb-disabled');
// ready
jQuery(document).trigger('woosb_check_ready', [
true,
is_selection,
is_unpurchasable,
is_empty,
is_min,
is_max,
is_total_min,
is_total_max,
$wrap]);
}
}
function woosb_save_ids($wrap) {
var ids = Array();
var wid = $wrap.attr('data-id');
var $ids = jQuery('.woosb-ids-' + wid);
var $products = $wrap.find('.woosb-products');
$products.find('.woosb-product').each(function() {
var $this = jQuery(this);
var id = parseInt($this.attr('data-id'));
var key = $this.attr('data-key');
var qty = parseFloat($this.attr('data-qty'));
var attrs = $this.attr('data-attrs');
if (id > 0 && qty > 0) {
if (attrs !== undefined) {
attrs = encodeURIComponent(attrs);
} else {
attrs = '';
}
ids.push(id + '/' + key + '/' + qty + '/' + attrs);
}
});
$ids.val(ids.join(','));
jQuery(document).trigger('woosb_save_ids', [ids, $wrap]);
}
function woosb_check_qty($qty) {
var $wrap = $qty.closest('.woosb-wrap');
var qty = parseFloat($qty.val());
var min = parseFloat($qty.attr('min'));
var max = parseFloat($qty.attr('max'));
if (qty === '' || isNaN(qty)) {
qty = 0;
}
if (!isNaN(min) && qty < min) {
qty = min;
}
if (!isNaN(max) && qty > max) {
qty = max;
}
$qty.val(qty);
$qty.closest('.woosb-product').attr('data-qty', qty);
// change subtotal
if (woosb_vars.bundled_price === 'subtotal' || woosb_vars.bundled_price ===
'subtotal_under_name') {
var $products = $wrap.find('.woosb-products');
var $product = $qty.closest('.woosb-product');
var price_suffix = $product.attr('data-price-suffix');
var ori_price = parseFloat($product.attr('data-price'));
var qty = parseFloat($product.attr('data-qty'));
$product.find('.woosb-price-ori').hide();
if (parseFloat($products.attr('data-discount')) > 0 &&
$products.attr('data-fixed-price') === 'no') {
var new_price = woosb_round(
(ori_price * (100 - parseFloat($products.attr('data-discount')))) /
100, woosb_vars.price_decimals);
$product.find('.woosb-price-new').
html(woosb_price_html(ori_price * qty, new_price * qty) +
price_suffix).
show();
} else {
$product.find('.woosb-price-new').
html(woosb_price_html(ori_price * qty) + price_suffix).
show();
}
}
jQuery(document).trigger('woosb_check_qty', [qty, $qty]);
woosb_init($wrap, 'woosb_check_qty');
}
function woosb_change_price($product, price, regular_price, price_html) {
var $products = $product.closest('.woosb-products');
var price_suffix = $product.attr('data-price-suffix');
var qty = parseFloat($product.attr('data-qty'));
var new_price_html = '';
// hide ori price
$product.find('.woosb-price-ori').hide();
// calculate new price
if (woosb_vars.bundled_price === 'subtotal' || woosb_vars.bundled_price ===
'subtotal_under_name') {
var ori_price = parseFloat(price);
if (woosb_vars.bundled_price_from === 'regular_price' && regular_price !==
undefined) {
ori_price = parseFloat(regular_price);
}
var new_price = ori_price;
if (parseFloat($products.attr('data-discount')) > 0) {
new_price = woosb_round(
(ori_price * (100 - parseFloat($products.attr('data-discount')))) /
100, woosb_vars.price_decimals);
}
new_price_html = woosb_price_html(ori_price * qty, new_price * qty) +
price_suffix;
} else {
if (parseFloat($products.attr('data-discount')) > 0) {
var ori_price = parseFloat(price);
if (woosb_vars.bundled_price_from === 'regular_price' && regular_price !==
undefined) {
ori_price = parseFloat(regular_price);
}
var new_price = woosb_round(
(ori_price * (100 - parseFloat($products.attr('data-discount')))) /
100, woosb_vars.price_decimals);
new_price_html = woosb_price_html(ori_price, new_price) + price_suffix;
} else {
if (woosb_vars.bundled_price_from === 'regular_price' && regular_price !==
undefined) {
new_price_html = woosb_price_html(regular_price) + price_suffix;
} else if (price_html !== '') {
new_price_html = price_html;
}
}
}
$product.find('.woosb-price-new').html(new_price_html).show();
jQuery(document).trigger('woosb_change_price', [$product, new_price_html]);
}
function woosb_round(value, decimals) {
return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
}
function woosb_format_money(number, places, symbol, thousand, decimal) {
number = number || 0;
places = !isNaN(places = Math.abs(places)) ? places : 2;
symbol = symbol !== undefined ? symbol : '$';
thousand = thousand !== undefined ? thousand : ',';
decimal = decimal !== undefined ? decimal : '.';
var negative = number < 0 ? '-' : '',
i = parseInt(number = Math.abs(+number || 0).toFixed(places), 10) + '',
j = 0;
if (i.length > 3) {
j = i.length % 3;
}
if (woosb_vars.trim_zeros === '1') {
return symbol + negative + (j ? i.substr(0, j) + thousand : '') +
i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + thousand) +
(places && (parseFloat(number) > parseFloat(i)) ? decimal +
Math.abs(number - i).
toFixed(places).
slice(2).
replace(/(\d*?[1-9])0+$/g, '$1') : '');
} else {
return symbol + negative + (j ? i.substr(0, j) + thousand : '') +
i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + thousand) +
(places ? decimal + Math.abs(number - i).toFixed(places).slice(2) : '');
}
}
function woosb_format_price(price) {
var price_html = '';
var price_formatted = woosb_format_money(price, woosb_vars.wc_price_decimals,
'', woosb_vars.wc_price_thousand_separator,
woosb_vars.wc_price_decimal_separator);
switch (woosb_vars.wc_price_format) {
case '%1$s%2$s':
//left
price_html += '' +
woosb_vars.wc_currency_symbol + '' + price_formatted;
break;
case '%1$s %2$s':
//left with space
price_html += '' +
woosb_vars.wc_currency_symbol + ' ' + price_formatted;
break;
case '%2$s%1$s':
//right
price_html += price_formatted +
'' +
woosb_vars.wc_currency_symbol + '';
break;
case '%2$s %1$s':
//right with space
price_html += price_formatted +
' ' +
woosb_vars.wc_currency_symbol + '';
break;
default:
//default
price_html += '' +
woosb_vars.wc_currency_symbol + ' ' + price_formatted;
}
price_html += '';
return price_html;
}
function woosb_price_html(regular_price, sale_price) {
var price_html = '';
if (parseFloat(woosb_round(sale_price, woosb_vars.wc_price_decimals)) <
parseFloat(woosb_round(regular_price, woosb_vars.wc_price_decimals))) {
price_html = '' + woosb_format_price(regular_price) + ' ' +
woosb_format_price(sale_price) + '';
} else {
price_html = woosb_format_price(regular_price);
}
return price_html;
}
function woosb_decimal_places(num) {
var match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
if (!match) {
return 0;
}
return Math.max(0, // Number of digits right of decimal point.
(match[1] ? match[1].length : 0) - // Adjust for scientific notation.
(match[2] ? +match[2] : 0));
}
function woosb_encode_entities(str) {
return String(str).
replace(/&/g, '&').
replace(//g, '>').
replace(/"/g, '"');
}
function woosb_decode_entities(str) {
var textArea = document.createElement('textarea');
textArea.innerHTML = str;
return textArea.value;
}